package com.sy.service.impl;

import com.sy.exception.BusinessException;
import com.sy.mapper.OrdersMapper;
import com.sy.service.OrderService;
import com.sy.utils.RandomUtils;
import com.sy.utils.RedisOperations;
import com.sy.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * description: OrderServiceImpl <br>
 * date: 2022/6/26 6:08 PM <br>
 * author: zoumaoji <br>
 * version: 1.0 <br>
 */

@Service
public class OrderServiceImpl extends AbstractBaseServiceImpl implements OrderService {
    @Autowired
    private RedisOperations redisOperations;
    @Autowired
    private OrdersMapper ordersMapper;
    @Override
    public String submitOrder(Integer[] subjectId, Integer memberId) {
        // 控制一定时间段内同一用户下单的数量，防止刷单现象（30s以内最多3单）-Redis
        //在Redis中设置一个key，设置过期时间为30s，
        //使用String作为数据类型，每次下单使用incr对其数量+1，达到3次后，提示用户不能频繁下单
        //30s过后由于key因为过期自动删除，所以提交次数的限制被解除！
        //key的命名： 体现出是哪个用户
        String orderSubmitTimeKey = "orderSubmitLimitTimes:" + memberId;
        if (redisOperations.exists(orderSubmitTimeKey)) {
            long times = Long.parseLong(redisOperations.get(orderSubmitTimeKey));
            if (times == 3L) {
                throw new BusinessException(HttpStatus.BAD_REQUEST,"请勿频繁提交订单");
            } else {
                redisOperations.incr(orderSubmitTimeKey);
            }
        } else {
            redisOperations.incr(orderSubmitTimeKey);
            redisOperations.expire(orderSubmitTimeKey, 30);
        }

        if (CollectionUtils.isEmpty(Arrays.asList(subjectId))) {
           throw new BusinessException("商品id不能为空");
        }

        String cartKey ="member:" + memberId;
        if (!redisOperations.exists(cartKey)) {
           throw new BusinessException("当前购物车为空");
        }

        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //获取当前用户对应的购物车中所有的商品的id
        Set<Integer> redisSubjectIds = redisOperations.hkeys(cartKey).stream()
                .map(subjectIdStr -> Integer.parseInt(subjectIdStr))
                .collect(Collectors.toSet());
        if (!redisSubjectIds.containsAll(Arrays.asList(subjectId))) {
           throw new BusinessException(HttpStatus.BAD_REQUEST,"选择的商品在购物车中可能不存在，请刷新页面后重试");
        }
        //插入订单表
        for (Integer sId:Arrays.asList(subjectId)){
            String format = formatter.format(calendar.getTime());
            ordersMapper.addOrder(sId,memberId,format);
        }
        //获取当前提交的所有商品id和对应的数量
        Map<String, String> redisCartItems = redisOperations.hgetall(cartKey);
        //清空购物车
        for (Map.Entry entry:redisCartItems.entrySet()){
            redisOperations.hdel(cartKey, (String) entry.getKey());
        }
        //注意：在设计表式有缺陷,所以这里就不再返回就有意义的订单号了,随机返回了。。。。
        String order = UuidUtils.generateUuid();
        return order;
    }
}
